// Include Files

// game
#include "IE\IE.h"
#include "IE\Game.h"

// scene
#include "IE\Scene.h"
#include "IE\Window.h"
#include "IE\Camera.h"
#include "IE\Object.h"

// manager assets
#include "IE\MeshAsset.h"
#include "IE\ShaderAsset.h"
#include "IE\TextureAsset.h"

// system nodes
#include "IE\InputNode.h"
#include "IE\PhysicsNode.h"
#include "IE\RenderNode.h"
#include "IE\ScriptNode.h"

// windows
#include <Windows.h>

/////////////////////////////////////////////////////////////////////////////////////
// Global Implementation
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
	// create the game
	IE::CGame *pGame = IE::CreateGame();
	pGame->Initialize();

	// load galleon assets
	IE::CMeshAsset *pGalleonPhysicsMeshAsset = IE::CreateMeshAsset();
	IE::CMeshAsset *pGalleonRenderMeshAsset = IE::CreateMeshAsset();
	IE::CShaderAsset *pGalleonShaderAsset = IE::CreateShaderAsset();
	IE::CTextureAsset *pGalleonTextureAsset = IE::CreateTextureAsset();

	// load sky assets
	IE::CMeshAsset *pSkyMeshAsset = IE::CreateMeshAsset();
	IE::CShaderAsset *pSkyShaderAsset = IE::CreateShaderAsset();
	IE::CTextureAsset *pSkyTextureAsset = IE::CreateTextureAsset();

	// load water assets
	IE::CMeshAsset *pWaterPhysicsMeshAsset = IE::CreateMeshAsset();
	IE::CMeshAsset *pWaterRenderMeshAsset = IE::CreateMeshAsset();
	IE::CShaderAsset *pWaterShaderAsset = IE::CreateShaderAsset();
	IE::CTextureAsset *pWaterTextureAsset = IE::CreateTextureAsset();

	// create the scene
	IE::CScene *pScene = IE::CreateScene();
	pScene->Initialize();

	IE::CInputNode *pSceneInputNode = IE::CreateInputNode();
	pScene->SetInputNode(pSceneInputNode);

	IE::CScriptNode *pSceneScriptNode = IE::CreateScriptNode();
	pScene->SetScriptNode(pSceneScriptNode);

	// create the window
	IE::CWindow *pWindow = IE::CreateGameWindow();
	pScene->SetWindow(pWindow);

	// create the camera
	IE::CCamera *pCamera = IE::CreateCamera();

	IE::CInputNode *pCameraInputNode = IE::CreateInputNode();
	pCamera->SetInputNode(pCameraInputNode);

	IE::CScriptNode *pCameraScriptNode = IE::CreateScriptNode();
	pCamera->SetScriptNode(pCameraScriptNode);

	pScene->SetCamera(pCamera);

	// create the galleon
	IE::CObject *pGalleon = IE::CreateObject();

	IE::CPhysicsNode *pGalleonPhysicsNode = IE::CreatePhysicsNode();
	pGalleon->SetPhysicsNode(pGalleonPhysicsNode);

	IE::CRenderNode *pGalleonRenderNode = IE::CreateRenderNode();
	pGalleon->SetRenderNode(pGalleonRenderNode);

	IE::CScriptNode *pGalleonScriptNode = IE::CreateScriptNode();
	pGalleon->SetScriptNode(pGalleonScriptNode);

	pScene->AddObject(pGalleon);

	// create the sky
	IE::CObject *pSky = IE::CreateObject();

	IE::CRenderNode *pSkyRenderNode = IE::CreateRenderNode();
	pSky->SetRenderNode(pSkyRenderNode);

	pScene->AddObject(pSky);

	// create the water
	IE::CObject *pWater = IE::CreateObject();

	IE::CPhysicsNode *pWaterPhysicsNode = IE::CreatePhysicsNode();
	pWater->SetPhysicsNode(pWaterPhysicsNode);

	IE::CRenderNode *pWaterRenderNode = IE::CreateRenderNode();
	pWater->SetRenderNode(pWaterRenderNode);

	IE::CScriptNode *pWaterScriptNode = IE::CreateScriptNode();
	pWater->SetScriptNode(pWaterScriptNode);

	pScene->AddObject(pWater);

	// run the scene
	pScene->Run();

	// destroy the water
	pScene->RemoveObject(pWater);

	pWater->SetScriptNode(NULL);
	IE::DestroyScriptNode(pWaterScriptNode);

	pWater->SetRenderNode(NULL);
	IE::DestroyRenderNode(pWaterRenderNode);

	pWater->SetPhysicsNode(NULL);
	IE::DestroyPhysicsNode(pWaterPhysicsNode);

	IE::DestroyObject(pWater);

	// destroy the sky
	pScene->RemoveObject(pSky);

	pSky->SetRenderNode(NULL);
	IE::DestroyRenderNode(pSkyRenderNode);

	IE::DestroyObject(pSky);

	// destroy the galleon
	pScene->RemoveObject(pGalleon);

	pGalleon->SetScriptNode(NULL);
	IE::DestroyScriptNode(pGalleonScriptNode);

	pGalleon->SetRenderNode(NULL);
	IE::DestroyRenderNode(pGalleonRenderNode);

	pGalleon->SetPhysicsNode(NULL);
	IE::DestroyPhysicsNode(pGalleonPhysicsNode);

	IE::DestroyObject(pGalleon);

	// destroy the camera
	pScene->SetCamera(NULL);

	pCamera->SetScriptNode(NULL);
	IE::DestroyScriptNode(pCameraScriptNode);

	pCamera->SetInputNode(NULL);
	IE::DestroyInputNode(pCameraInputNode);

	IE::DestroyCamera(pCamera);

	// destroy the window
	pScene->SetWindow(NULL);
	IE::DestroyGameWindow(pWindow);

	// destroy the scene
	pScene->Shutdown();

	pScene->SetScriptNode(NULL);
	IE::DestroyScriptNode(pSceneScriptNode);

	pScene->SetInputNode(NULL);
	IE::DestroyInputNode(pSceneInputNode);

	IE::DestroyScene(pScene);

	// destroy galleon assets
	IE::DestroyTextureAsset(pGalleonTextureAsset);
	IE::DestroyShaderAsset(pGalleonShaderAsset);
	IE::DestroyMeshAsset(pGalleonRenderMeshAsset);
	IE::DestroyMeshAsset(pGalleonPhysicsMeshAsset);

	// destroy sky assets
	IE::DestroyTextureAsset(pSkyTextureAsset);
	IE::DestroyShaderAsset(pSkyShaderAsset);
	IE::DestroyMeshAsset(pSkyMeshAsset);

	// destroy water assets
	IE::DestroyTextureAsset(pWaterTextureAsset);
	IE::DestroyShaderAsset(pWaterShaderAsset);
	IE::DestroyMeshAsset(pWaterRenderMeshAsset);
	IE::DestroyMeshAsset(pWaterPhysicsMeshAsset);

	// destroy the game
	pGame->Shutdown();
	IE::DestroyGame(pGame);

	// complete
	return 0;
}
